package aViewLayer;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Image;
import java.io.File;
import java.io.InputStream;

import javax.imageio.ImageIO;

import aControllerLayer.BattleController;
import aModelLayer.Battle;
import aModelLayer.BattleCharacter;
import aModelLayer.BattleEnemy;
import aModelLayer.Game;
import aModelLayer.Menu;
import aaGame.RpgGamePanel;

public class BattleView extends View {
	Game mModel;
	Battle battle;
	BattleController controller;
	Menu battleMenu;
	Menu targetSelectMenu;
	BattleCharacter[] battleCharacters;
	BattleEnemy[] battleEnemies;
	
	private Font font;
	private FontMetrics fm;
	
	public Image menuArrow2;
	public Image menuArrow3;
	public Image menuArrow4;
	public Image background;
	public Image[] characterSprites;
	public Image[] enemySprites;
	
	boolean menuAccess;
	boolean targetSelectAccess;
	
	public BattleView(Game model, BattleController controller) {
		mModel = model;
		this.controller = controller;
		battleMenu = controller.getBattleMenu();
		
		battleCharacters = model.getBattleCharacters();
		
		menuAccess = false;
		
		try {
			InputStream is = this.getClass().getResourceAsStream(
					"/fonts/PetMe128.ttf");
			font = Font.createFont(Font.TRUETYPE_FONT, is);
			font = font.deriveFont(24.0f);

			menuArrow2 = ImageIO.read(new File(this.getClass().getResource("/images/menuArrow2.png").toURI()));
			menuArrow3 = ImageIO.read(new File(this.getClass().getResource("/images/menuArrow3.png").toURI()));
			menuArrow4 = ImageIO.read(new File(this.getClass().getResource("/images/menuArrow4.png").toURI()));
			background = ImageIO.read(new File(this.getClass().getResource("/images/battle_background.png").toURI()));
			
			characterSprites = new Image[battleCharacters.length];
			characterSprites[0] = ImageIO.read(new File(this.getClass().getResource("/sprites/Warrior_Idle.png").toURI()));
			characterSprites[1] = ImageIO.read(new File(this.getClass().getResource("/sprites/Mage_Idle.png").toURI()));
			characterSprites[2] = ImageIO.read(new File(this.getClass().getResource("/sprites/Thief_Idle.png").toURI()));
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void render(Graphics2D g, RpgGamePanel root) {
		// TODO Auto-generated method stub
		g.drawImage(background, 0, 0, root.getWidth(), root.getHeight(), 0, 0, background.getWidth(null), background.getHeight(null), null);
		
		g.setColor(Color.WHITE);
		g.setStroke(new BasicStroke(20));
		g.drawRoundRect(8, (2 * root.getHeight() / 3), (root.getWidth() / 3) - 18,
				(root.getHeight() / 3) - 10, 8, 8);
		g.drawRoundRect((root.getWidth() / 3) + 12, (2 * root.getHeight() / 3), (2 * root.getWidth() / 3) - 22,
				(root.getHeight() / 3) - 10, 8, 8);
		
		GradientPaint gradient = new GradientPaint(0, 0, Color.BLUE,
				root.getWidth(), root.getHeight(), Color.BLACK, true);
		g.setPaint(gradient);
		g.fillRoundRect(5, (2 * root.getHeight() / 3) - 3, (root.getWidth() / 3) - 10,
				(root.getHeight() / 3) - 3, 15, 15);
		g.fillRoundRect((root.getWidth() / 3) + 8, (2 * root.getHeight() / 3) - 3, (2 * root.getWidth() / 3) - 14,
				(root.getHeight() / 3) - 3, 15, 15);
		
		g.setPaint(null);
		
		g.setColor(Color.WHITE);
		font = font.deriveFont(12.0f);
		g.setFont(font);
		fm = g.getFontMetrics();
		drawString(g, "HP", (root.getWidth() / 3) + 20, (2 * root.getHeight() / 3) + 20, root.getWidth());
		drawString(g, "MP", (root.getWidth() / 3) + 46 + (2 * (root.getWidth() - 100) / 9), (2 * root.getHeight() / 3) + 20, root.getWidth());
		drawString(g, "Action", (root.getWidth() / 3) + 15 + (4 * (root.getWidth() - 100) / 9), (2 * root.getHeight() / 3) + 20, root.getWidth());
		
		int lineHeight = fm.getHeight();
		int yOffset = (2 * root.getHeight() / 3) + 40;
		for (int i = 0; i < battleCharacters.length; i++) {
			g.setColor(Color.WHITE);
			font = font.deriveFont(18.0f);
			g.setFont(font);
			fm = g.getFontMetrics();
			drawString(g, battleCharacters[i].getName(), 20,
					yOffset + 5, root.getWidth());
			
			font = font.deriveFont(12.0f);
			g.setFont(font);
			fm = g.getFontMetrics();
			drawString(g, battleCharacters[i].getCurrentHealth() + "/" + battleCharacters[i].getMaxHealth(), (root.getWidth() / 3) + 20, yOffset, root.getWidth());
			drawString(g, battleCharacters[i].getCurrentMana() + "/" + battleCharacters[i].getMaxMana(), (root.getWidth() / 3) + 46 + (2 * (root.getWidth() - 100) / 9), yOffset, root.getWidth());
			
			g.setColor(Color.RED);
			g.fillRect((root.getWidth() / 3) + 20, yOffset - lineHeight + 20, (2 * root.getWidth() / 9), 5);			
			g.setColor(Color.GREEN);
			g.fillRect((root.getWidth() / 3) + 20, yOffset - lineHeight + 20, 
					(2 * (root.getWidth()) / 9) - ((2 * (root.getWidth()) / 9) - (((2 * (root.getWidth()) / 9) * battleCharacters[i].getCurrentHealth()) / battleCharacters[i].getMaxHealth())), 5);
			
			g.setColor(Color.GRAY);
			g.fillRect((root.getWidth() / 3) + 46 + (2 * (root.getWidth() - 100) / 9), yOffset - lineHeight + 20, ((root.getWidth() - 100) / 9), 5);			
			g.setColor(Color.CYAN);
			g.fillRect((root.getWidth() / 3) + 46 + (2 * (root.getWidth() - 100) / 9), yOffset - lineHeight + 20, 
					((root.getWidth() - 100) / 9) - (((root.getWidth() - 100) / 9) - ((((root.getWidth() - 100) / 9) * battleCharacters[i].getCurrentMana()) / battleCharacters[i].getMaxMana())), 5);

			g.setColor(Color.GRAY);
			g.fillRect((root.getWidth() / 3) + 15 + (4 * (root.getWidth() - 100) / 9), yOffset - lineHeight + 5, (2 * (root.getWidth() - 100) / 9) + 10, 25);
			
			g.setColor(Color.DARK_GRAY);
			g.fillRect((root.getWidth() / 3) + 20 + (4 * (root.getWidth() - 100) / 9), yOffset - lineHeight + 10, (2 * (root.getWidth() - 100) / 9), 15);
			
			g.setColor(Color.WHITE);
			g.fillRect((root.getWidth() / 3) + 20 + (4 * (root.getWidth() - 100) / 9), yOffset - lineHeight + 10, 
					(2 * (root.getWidth() - 100) / 9) - ((2 * (root.getWidth() - 100) / 9) - (((2 * (root.getWidth() - 100) / 9) * battleCharacters[i].getCurrentActionBar()) / BattleCharacter.actionBarMax)), 15);

			yOffset += lineHeight + 35;
		}
		
		for (int i = 0; i < characterSprites.length; i++) {
			int x = (3 * root.getWidth() / 4) + (i * 40);
			int y = (root.getHeight() / 2) - ((characterSprites.length - (i + 1)) * 100) - 20;
			g.drawImage(characterSprites[i], x, y, x + (2 * characterSprites[i].getWidth(null)), y + (2 * characterSprites[i].getHeight(null)), 0, 0, characterSprites[i].getWidth(null), characterSprites[i].getHeight(null), null);
		}
		
		
		for (int i = 0; i < enemySprites.length; i++) {
			if (!battleEnemies[i].isDead()) {
				int x = (root.getWidth() / 4) + (i * 30);
				int y = (root.getHeight() / 2) - ((enemySprites.length - (i + 1)) * 80) + 20;
				g.drawImage(enemySprites[i], x, y, x + (3 * enemySprites[i].getWidth(null)), y + (3 * enemySprites[i].getHeight(null)), 0, 0, enemySprites[i].getWidth(null), enemySprites[i].getHeight(null), null);
			}
		}
		
		
		if (menuAccess || targetSelectAccess) {
			
			g.setColor(Color.WHITE);
			g.drawRoundRect((root.getWidth() / 6) - 8, (2 * root.getHeight() / 3), (root.getWidth() / 6) - 2,
					(root.getHeight() / 3) - 10, 8, 8);
			
			gradient = new GradientPaint(0, 0, Color.BLUE,
					root.getWidth(), root.getHeight(), Color.BLACK, true);
			g.setPaint(gradient);
			g.fillRoundRect((root.getWidth() / 6) - 11, (2 * root.getHeight() / 3) - 3, (root.getWidth() / 6) + 6,
					(root.getHeight() / 3) - 3, 15, 15);
			
			g.setPaint(null);
			g.setColor(Color.WHITE);
			font = font.deriveFont(16.0f);
			g.setFont(font);
			fm = g.getFontMetrics();
			lineHeight = fm.getHeight();
			yOffset = ((2 * root.getHeight()) / 3) + 30;
			for (int i = 0; i < battleMenu.getOptions().size(); i++) {
				drawString(g, battleMenu.getOptions().get(i), (root.getWidth() / 3) - 115,
						yOffset, root.getWidth() / 3);
				if (battleMenu.getOptions().get(i).equals(battleMenu.getCurrentOption())) {
					g.drawImage(menuArrow2, (root.getWidth() / 3) - 135,
							yOffset - lineHeight,
							(root.getWidth() / 3) - 120, yOffset, 0, 0,
							menuArrow2.getWidth(null),
							menuArrow2.getHeight(null), null);
				}

				yOffset += lineHeight + 15;
			}
			
			int activeCharacter = controller.getAvailableAction().get(0);
			int x = (3 * root.getWidth() / 4) + (activeCharacter * 40);
			int y = (root.getHeight() / 2) - ((characterSprites.length - (activeCharacter + 1)) * 100) - 60;
			g.drawImage(menuArrow3, x, y, x + (2 * menuArrow3.getWidth(null)), y + (2 * menuArrow3.getHeight(null)), 0, 0, menuArrow3.getWidth(null), menuArrow3.getHeight(null), null);
		}
		
		if (targetSelectAccess) {
			g.setPaint(null);
			
			for (int i = 0; i < targetSelectMenu.getOptions().size(); i++) {
				if (targetSelectMenu.getOptions().get(i).equals(targetSelectMenu.getCurrentOption())) {
					int enemySelected = Integer.parseInt(targetSelectMenu.getCurrentOption());
					int x = (root.getWidth() / 4) + (enemySelected * 30) + (4 * enemySprites[enemySelected].getWidth(null));
					int y = (root.getHeight() / 2) - ((enemySprites.length - (enemySelected + 1)) * 80) + (2 * enemySprites[enemySelected].getHeight(null));
					g.drawImage(menuArrow4, x, y, x + (menuArrow4.getWidth(null)), y + (menuArrow4.getHeight(null)), 0, 0, menuArrow4.getWidth(null), menuArrow4.getHeight(null), null);
				}
			}
		}
		
	}
	
	public void drawString(Graphics2D g, String s, int x, int y, int width) {
		FontMetrics fm = g.getFontMetrics();

		int lineHeight = fm.getHeight();

		int xOffset = x;
		int yOffset = y;

		String[] words = s.split(" ");

		for (String word : words) {
			int wordWidth = fm.stringWidth(word + " ");

			if (xOffset + wordWidth >= x + width) {
				yOffset += lineHeight;
				xOffset = x;
			}

			g.drawString(word, xOffset, yOffset);

			xOffset += wordWidth;
		}
	}
	
	public void startNewBattle(Battle battle, BattleEnemy[] battleEnemies) {
		this.battle = battle;
		this.battleEnemies = battleEnemies;
		
		try {

			enemySprites = new Image[battleEnemies.length];
			for (int i = 0; i < enemySprites.length; i++)
				enemySprites[i] = ImageIO.read(new File(this.getClass().getResource("/sprites/slime.png").toURI()));
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void setMenuAccess(boolean menuAccess) {
		this.menuAccess = menuAccess;
	}
	
	public void setTargetSelectAccess(boolean targetSelectAccess) {
		this.targetSelectAccess = targetSelectAccess;
		
		if (targetSelectAccess = true)
			targetSelectMenu = controller.getTargetSelectMenu();
	}

}
